from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import json
import datetime


class Train12306:
    def __init__(self):
        self.login_url = "https://kyfw.12306.cn/otn/resources/login.html"
        self.driver = webdriver.Chrome()
        self.wait = WebDriverWait(self.driver, 10)

        # 配置信息
        self.config = {
            "username": "你的用户名",
            "password": "你的密码",
            "from_station": "北京",
            "to_station": "上海",
            "train_date": "2024-04-01",
            "passengers": ["乘客姓名1", "乘客姓名2"],
            "train_numbers": ["G101", "G102"]  # 期望的车次
        }

    def login(self):
        """登录12306"""
        self.driver.get(self.login_url)
        print("请在30秒内完成登录验证...")

        # 输入用户名和密码
        self.driver.find_element(By.ID, "J-userName").send_keys(self.config["username"])
        self.driver.find_element(By.ID, "J-password").send_keys(self.config["password"])

        # 等待用户手动完成验证码验证和登录
        time.sleep(30)

    def search_ticket(self):
        """搜索车票"""
        # 跳转到车票预订页面
        self.driver.get("https://kyfw.12306.cn/otn/leftTicket/init")

        # 输入出发地和目的地
        from_input = self.wait.until(EC.presence_of_element_located((By.ID, "fromStation")))
        to_input = self.wait.until(EC.presence_of_element_located((By.ID, "toStation")))

        from_input.clear()
        from_input.send_keys(self.config["from_station"])
        to_input.clear()
        to_input.send_keys(self.config["to_station"])

        # 选择出发日期
        date_input = self.wait.until(EC.presence_of_element_located((By.ID, "train_date")))
        self.driver.execute_script(f'document.getElementById("train_date").value="{self.config["train_date"]}"')

        # 点击查询按钮
        search_button = self.wait.until(EC.element_to_be_clickable((By.ID, "query_ticket")))
        search_button.click()

    def book_ticket(self):
        """订票"""
        while True:
            try:
                # 等待车次列表加载
                time.sleep(2)
                trains = self.wait.until(
                    EC.presence_of_all_elements_located((By.XPATH, "//tr[contains(@id, 'ticket_')]")))

                for train in trains:
                    train_number = train.find_element(By.CLASS_NAME, "number").text

                    if train_number in self.config["train_numbers"]:
                        # 检查是否有票
                        if "有" in train.text or "1" in train.text or "2" in train.text:
                            # 点击预订按钮
                            book_button = train.find_element(By.CLASS_NAME, "btn72")
                            book_button.click()

                            # 选择乘客
                            self.select_passengers()
                            return True

                print(f"当前时间: {datetime.datetime.now()}, 未找到符合条件的车票，继续查询...")
                self.driver.refresh()

            except Exception as e:
                print(f"发生错误: {str(e)}")
                self.driver.refresh()

    def select_passengers(self):
        """选择乘客"""
        # 等待乘客列表加载
        time.sleep(2)
        for passenger in self.config["passengers"]:
            checkbox = self.wait.until(EC.presence_of_element_located(
                (By.XPATH, f"//label[contains(text(), '{passenger}')]/preceding-sibling::input")))
            checkbox.click()

        # 提交订单
        submit_button = self.wait.until(EC.element_to_be_clickable((By.ID, "submitOrder_id")))
        submit_button.click()

    def run(self):
        """运行抢票程序"""
        try:
            self.login()
            self.search_ticket()
            self.book_ticket()
            print("抢票成功！请在30分钟内完成支付。")
        except Exception as e:
            print(f"程序异常: {str(e)}")
        finally:
            self.driver.quit()


if __name__ == "__main__":
    bot = Train12306()
    bot.run()